package com.sk.bilibili.apiMapper.component;

import com.sk.bilibili.apiMapper.bean.Args;
import com.sk.bilibili.apiMapper.interfaces.MethodHandler;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 邵康
 * @date 2021/7/11 9:44
 */
@Slf4j
public class HttpSender {

    private OkHttpClient okHttpClient;
    private Map<String, MethodHandler> handlerMap;
    private boolean logInfo;

    public void setLogInfo(boolean logInfo) {
        this.logInfo = logInfo;
    }

    public HttpSender() {
        handlerMap=new HashMap<>();
    }

    public void addMethodHandler(MethodHandler methodHandler){
        handlerMap.put(methodHandler.handleType(),methodHandler);
    }

    public void setOkHttpClient(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    public void initOkHttpClient() {
        if(okHttpClient!=null)return;
        okHttpClient=new OkHttpClient();
    }

    @SneakyThrows
    public String send(String url, String method, Map<String, String> addHeaders, List<String> removeHeaders,
                       Args args) {
        Request.Builder builder = new Request.Builder().url(url);
        handleHeader(builder,removeHeaders,addHeaders);
        builder=handleMethod(builder,method,args);
        Request request = builder.build();
        logInfo(request);
        return okHttpClient.newCall(request).execute().body().string();
    }

    private void logInfo(Request request) {
        if(!logInfo)return;
        log.info("URL:{}",request.url());
        log.info("METHOD:{}",request.method());
        Map<String, List<String>> multimap = request.headers().toMultimap();
        log.info("HEADERS");
        for (Map.Entry<String,List<String>> entry:multimap.entrySet()){
            log.info("{}:{}",new Object[]{entry.getKey(),entry.getValue()});
        }
    }

    private Request.Builder handleMethod(Request.Builder builder, String method, Args args) {
        MethodHandler handler = handlerMap.get(method);
        if(handler==null)throw new RuntimeException("没有处理"+method+"请求的处理器!");
        return handler.handle(builder, args);
    }

    private void handleHeader(Request.Builder builder, List<String> removeHeaders, Map<String, String> addHeaders) {
        for (String key:removeHeaders){
            builder.removeHeader(key);
        }
        for (Map.Entry<String,String> entry:addHeaders.entrySet()){
            builder.addHeader(entry.getKey(),entry.getValue());
        }
    }

}
